package wrapper

import (
	"hash"

	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/providers/core"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/thirdparty/ichain/security/csp"
)

// NewCryptoSuite 对ichain csp的封装
// @param csp
// @param isGM
// @return core.CryptoSuite
func NewCryptoSuite(csp csp.CSP, isGM bool) core.CryptoSuite {
	return &CryptoSuite{
		CSP:  csp,
		isGM: isGM,
	}
}

func GetKey(newkey csp.Key) core.Key {
	return &key{newkey}
}

type CryptoSuite struct {
	CSP  csp.CSP
	isGM bool
}

func (c *CryptoSuite) KeyGen(opts core.KeyGenOpts) (k core.Key, err error) {
	key, err := c.CSP.KeyGenerate(opts)
	return GetKey(key), err
}

func (c *CryptoSuite) KeyImport(raw interface{}, opts core.KeyImportOpts) (k core.Key, err error) {
	key, err := c.CSP.KeyImport(raw, opts)
	return GetKey(key), err
}

func (c *CryptoSuite) GetKey(ski []byte) (k core.Key, err error) {
	key, err := c.CSP.GetKey(ski, nil)
	return GetKey(key), err
}

func (c *CryptoSuite) Hash(msg []byte) (hash []byte, err error) {
	return c.CSP.Hash(msg, nil)
}

func (c *CryptoSuite) GetHash() (h hash.Hash, err error) {
	return c.CSP.GetHash(), nil
}

func (c *CryptoSuite) Sign(k core.Key, digest []byte, opts core.SignerOpts) (signature []byte, err error) {
	return c.CSP.Sign(k.(*key).key, digest, nil)
}

func (c *CryptoSuite) Verify(k core.Key, signature, digest []byte, opts core.SignerOpts) (valid bool, err error) {
	return c.CSP.Verify(k.(*key).key, signature, digest, nil)
}

func (c *CryptoSuite) IsGM() bool {
	return c.isGM
}

type key struct {
	key csp.Key
}

func (k *key) Bytes() ([]byte, error) {
	return k.key.Bytes()
}

func (k *key) SKI() []byte {
	ski, _ := k.key.SKI()
	return ski
}

func (k *key) PublicKey() (core.Key, error) {
	key, err := k.key.PublicKey()
	return GetKey(key), err
}
